package com.tsd.system.service.impl;

import com.tsd.common.vo.BatchDeleteLogicVo;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.ListUtil;
import com.tsd.core.vo.HlpException4Login;
import com.tsd.core.vo.PageBean;
import com.tsd.service.BaseServiceImpl;
import com.tsd.system.SysConstants;
import com.tsd.system.dao.SysResourceMapper;
import com.tsd.system.dao.SysUserMapper;
import com.tsd.system.dao.SysUserResourceMapper;
import com.tsd.system.dao.SysUserRoleMapper;
import com.tsd.system.entity.*;
import com.tsd.system.service.SysUserResourceService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 描述：SysUserResource 服务实现层
 *
 * @author Hillpool
 * @date 2019/03/12 12:20:51
 */
@Service
public class SysUserResourceServiceImpl extends BaseServiceImpl implements SysUserResourceService {

    @Resource
    private SysUserResourceMapper sysUserResourceMapper;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;
    @Resource
    private SysResourceMapper sysResourceMapper;
    @Resource
    SysUserMapper sysUserMapper;

    @Override
    public SysUserResource getSysUserResourceById(Long id) throws Exception {
        return sysUserResourceMapper.selectByPrimaryKey(id);
    }

    @Override
    public void saveSysUserResource(SysUserResource record) throws Exception {
        if (HlpUtils.isEmpty(record.getId())) {
            SysUserResource old = sysUserResourceMapper.selectByObj(record);
            if (old == null) {
                sysUserResourceMapper.insertSelective(record);
            }
        } else {
            sysUserResourceMapper.updateByPrimaryKeySelective(record);
        }
    }

    @Override
    public void deleteSysUserResource(Long id) throws Exception {
        sysUserResourceMapper.deleteByPrimaryKey(id);
    }

    @Override
    public List<SysUserResourceExt> findSysUserResources(Map<String, Object> params, PageBean page) throws Exception {
        return sysUserResourceMapper.selectByPage(params, page);
    }

    @Override
    synchronized public void updateFromInheritedByUserRole() throws Exception {
        List<SysUserRole> list = sysUserRoleMapper.selectSync();
        for (SysUserRole userRole : list) {
            updateResourceById(userRole.getUser_sid(), userRole.getRole_sid(), userRole.getDr());
            sysUserRoleMapper.updateSynced(userRole.getId());
        }
    }

    @Override
    public void deleteSysUserResource(SysUser sysUser, String userId, List<String> resourceIdList) throws Exception {
        for (String id : resourceIdList) {
            SysUserResource t = new SysUserResource();
            t.setUser_sid(userId);
            t.setRes_sid(id);
            SysUserResource old = sysUserResourceMapper.selectByObj(t);
            if (old != null && old.getInherit_role_sid() == null && old.getInherit_group_sid() == null) {
                sysUserResourceMapper.deleteByPrimaryKey(old.getId());
            }
        }
    }

    @Override
    public void deleteSysUserResource(SysUser sysUser, String userId) throws Exception {
        sysUserResourceMapper.deleteByUserSid(userId);
    }

    @Override
    public List<SysResourceExt> queryTree4UserId(String parentCode, String userId) throws Exception {
        SysUser sysUser = sysUserMapper.selectBySid(userId);
        Map<String, Object> params = new HashMap<>();
        params.put("userSid", userId);
        List<SysUserRoleExt> roles = sysUserRoleMapper.selectByUserSid(params);
        params.clear();
        params.put("parentCode", parentCode);
        params.put("groupSid", sysUser.getGroup_sid());
        List<SysResourceExt> list = null;
        if (roles != null && roles.size() > 0) {
            params.put("roleSid", roles.get(0).getRole_sid());
            list = sysResourceMapper.selectByParentId4GroupSidRoleSid(params);
            for (SysResourceExt t : list) {
                expandResource4User(t, params);
            }
        }
        return list;
    }

    @Override
    public void saveSysResourceList2User(SysUser opUser, String userId, List<String> resourceIdList) throws Exception {
        List<SysUserResourceExt> old = findSysUserResourceByUserSid(userId);
        List<Long> delIds = ListUtil.map(old, SysUserResource::getId);
        if (!HlpUtils.isEmptyList(delIds)) {
            BatchDeleteLogicVo logicVo = new BatchDeleteLogicVo();
            logicVo.setIdList(delIds);
            sysUserResourceMapper.deleteByIdList(logicVo);
        }
        if (!HlpUtils.isEmptyList(resourceIdList)) {
            List<SysUserResourceExt> insertList = new ArrayList<>();
            List<SysUserResourceExt> updateList = new ArrayList<>();
            List<SysUserResourceExt> oldList = sysUserResourceMapper.selectByUserSid(userId);
            for (String id : resourceIdList) {
                SysUserResourceExt resourceExt = new SysUserResourceExt();
                resourceExt.setRes_sid(id);
                resourceExt.setUser_sid(userId);
                resourceExt.setAuth_mode(1);
                SysUserResource oldData = ListUtil.get(oldList, t -> id.equals(t.getRes_sid()));
                if (oldData != null) {
                    resourceExt.setId(oldData.getId());
                    updateList.add(resourceExt);
                } else {
                    insertList.add(resourceExt);
                }
                if (insertList.size() == 100) {
                    sysUserResourceMapper.insertList(insertList);
                    insertList.clear();
                }
                if (updateList.size() == 100) {
                    sysUserResourceMapper.updateList(updateList);
                    updateList.clear();
                }
            }
            if (!HlpUtils.isEmptyList(insertList)) {
                sysUserResourceMapper.insertList(insertList);
            }
            if (!HlpUtils.isEmptyList(updateList)) {
                sysUserResourceMapper.updateList(updateList);
            }
        }
    }

    @Override
    public List<SysUserResourceExt> findSysUserResourceByUserSid(String userSid) {
        return sysUserResourceMapper.selectByUserSid(userSid);
    }

    @Override
    public List<SysResourceExt> queryTree4UserIdNew(String parentCode, String userId) throws Exception {
        List<SysResourceExt> resourceList = sysResourceMapper.selectByParentCode4UserId(parentCode, userId);
        if (!HlpUtils.isEmptyList(resourceList)) {
            SysResourceExt application = ListUtil.get(resourceList, t -> parentCode.equals(t.getCode()));
            if (application != null) {
                List<SysResourceExt> list = ListUtil.filterSorted(resourceList, t -> application.getSid().equals(t.getParent_sid()),
                        Comparator.comparing(SysResource::getSn));
                if (!HlpUtils.isEmptyList(list)) {
                    for (SysResourceExt resource : list) {
                        this.extendResourceTree4New(resourceList, resource);
                    }
                }
                return list;
            }
        }
        return null;
    }

    @Override
    public List<SysResourceExt> queryTree4UserIdRole(List<String> parentCode, String userId) throws Exception {
        SysUser sysUser = sysUserMapper.selectBySid(userId);
        if (sysUser == null) {
            throw new HlpException4Login("当前用户信息有误");
        }
        List<SysResourceExt> resourceList = null;
        if (SysConstants.LOGIN_ID4ADMIN.equals(sysUser.getLogin_id())) {
            //如果是admin登录账号，只能获取授权中心
            parentCode.clear();
            parentCode.add(SysConstants.PARENT_CODE4AUTH_CENTER);
            resourceList = sysResourceMapper.selectByParentId4Admin(parentCode);
        } else {
            resourceList = sysResourceMapper.selectByParentId4UserIdFromRole(parentCode, userId);
        }
        if (!HlpUtils.isEmptyList(resourceList)) {
            List<SysResourceExt> list = ListUtil.filterSorted(resourceList, t -> t.getFull_code().equals(t.getCode() + "."),
                    Comparator.comparing(SysResource::getSn));
            if (!HlpUtils.isEmptyList(list)) {
                for (SysResourceExt resource : list) {
                    this.extendResourceTree4New(resourceList, resource);
                }
            }
            return list;
        }
        return null;
    }

    private void extendResourceTree4New(List<SysResourceExt> resourceList, SysResourceExt parent) {
        if (parent != null) {
            //&& parent.getChild_count() != null && parent.getChild_count() > 0
            //为了避免数据是导入的方式，此处不判断子级数量
            List<SysResourceExt> childs = ListUtil.filterSorted(resourceList, t -> parent.getSid().equals(t.getParent_sid()),
                    Comparator.comparing(SysResource::getSn));
            if (!HlpUtils.isEmptyList(childs)) {
                for (SysResourceExt ext : childs) {
                    List<String> strs = new ArrayList<>();
                    if (!HlpUtils.isEmpty(parent.getParent_name())) {
                        strs.add(parent.getParent_name());
                    }
                    strs.add(parent.getName());
                    ext.setParent_name(StringUtils.join(strs, ","));
                }
                parent.setChildrens(childs);
                parent.setChild_count(childs.size());
                for (SysResourceExt resource : childs) {
                    this.extendResourceTree4New(resourceList, resource);
                }
            } else {
                parent.setChild_count(0);
            }
        }
    }

    private void updateResourceById(String userId, String roleId, int dr) {
        SysUserResource t = new SysUserResource();
        t.setUser_sid(userId);
        t.setInherit_role_sid(roleId);
        if (dr == 0) {
            sysUserResourceMapper.deleteLogicNotInRoleByUserRole(t);
            sysUserResourceMapper.insertByUserRole(t);
        } else {
            sysUserResourceMapper.deleteByUserRole(t);
        }
    }

    private void expandResource4User(SysResourceExt resource, Map<String, Object> params) {
        if (resource.getChild_count() != null && resource.getChild_count() > 0) {
            params.put("parentCode", resource.getCode());
            List<SysResourceExt> childs = sysResourceMapper.selectByParentId4GroupSidRoleSid(params);
            if (!HlpUtils.isEmptyList(childs)) {
                resource.setChildrens(childs);
                resource.setChild_count(childs.size());
                for (SysResourceExt t : childs) {
                    expandResource4User(t, params);
                }
            } else {
                resource.setChild_count(0);
            }
        }
    }
}
